package com.erp.aopLog;

import cn.hutool.core.date.DateUtil;
import com.erp.entity.Adminlog;
import com.erp.enums.statusCode;
import com.erp.mapper.AdminlogMapper;
import com.erp.security.dto.JwtUserDto;
import eu.bitwalker.useragentutils.UserAgent;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;


/** 系统日志：切面处理类 */
@Aspect
@Component
public class SysLogAspect {
    /**我这里是使用log4j2把一些信息打印在控制台上面，可以不写 */
    private static final Logger log = LogManager.getLogger(SysLogAspect.class);

    /**操作数据库 */
    @Resource
    private AdminlogMapper adminlogMapper;

    //定义切点 @Pointcut
    //在注解的位置切入代码
    @Pointcut("@annotation(com.erp.aopLog.MyLog)")
    public void logPoinCut() {
    }

    //切面 配置通知
    @Before("logPoinCut()")         //AfterReturning
    public void saveOperation(JoinPoint joinPoint) {
        log.info("---------------接口日志记录---------------");
        //用于保存日志
        Adminlog adminLog = new Adminlog();

        //从切面织入点处通过反射机制获取织入点处的方法
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        //获取切入点所在的方法
        Method method = signature.getMethod();

        //获取操作--方法上的Log的值
        MyLog myLog = method.getAnnotation(MyLog.class);
        if (myLog != null) {
            //保存操作事件
            String moduleName = myLog.moduleName();
            adminLog.setModuleName(moduleName);

            //保存日志类型
            int type = myLog.type();
            adminLog.setType(type);

            log.info("operation="+moduleName+",type="+type);
        }

        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String requestURL = request.getRequestURI();
        adminLog.setUrl(requestURL);
        // 客户端ip
        String ip = request.getRemoteAddr();
        adminLog.setLoginIp(ip);
        // 操作人账号、姓名（需要提前将用户信息存到session）
        //        获取用户信息
        JwtUserDto jwtUserDto = (JwtUserDto) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
//        Integer userId = jwtUserDto.getMyUser().getUserId();
//        AdminUser user = (AdminUser) request.getSession().getAttribute("user");
        if(jwtUserDto != null) {
            Integer userId = jwtUserDto.getMyUser().getUserId();
            String userName = jwtUserDto.getMyUser().getUserName();
            adminLog.setUserId(userId);
            adminLog.setUserName(userName);
        }
        log.info("url="+requestURL,"ip="+ip);

        adminLog.setCreatetime(DateUtil.now());
        //调用service保存Operation实体类到数据库
        //我id使用的是UUID，不需要的可以注释掉
//        String id = UUIDUtil.getUUID();
//        adminLog.setId(id);
        //浏览器信息
        UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));
        adminLog.setBrowser(userAgent.getBrowser().getName());
        //数据状态
        adminLog.setStatus(statusCode.Default.getValue());
        adminlogMapper.insert(adminLog);
    }
}
